/*
 * Copyright (c) 2010-2011 Josef Hardi <josef.hardi@gmail.com>
 * Copyright (c) 2010 Piotr Zagawa <piotr.zagawa@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package id.duapuluhdua.dakidaki.data.common;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

import android.content.ContentValues;
import android.database.Cursor;

/**
 *
 */
public class DataValues
{
  /** Fields */
  private static TimeZone timeZone = TimeZone.getDefault();
  private SimpleDateFormat mDateFormat;

  private DataTable mTable;
  private Cursor mInputCursor;
  private ContentValues mValues;

  /**
   * Default constructor for insert/update mode (output values).
   *
   * @param table
   *            The database table object.
   */
  public DataValues(DataTable table)
  {
    mTable = table;

    mDateFormat = new SimpleDateFormat();
    mValues = new ContentValues();
  }

  /**
   * Default constructor for edit mode (input values).
   *
   * @param table
   *            The database table object.
   * @param inputCursor
   *            The input cursor.
   */
  public DataValues(DataTable table, Cursor inputCursor)
  {
    mTable = table;
    mInputCursor = inputCursor;

    getValuesFromCursor();
  }

  public void clearAll()
  {
    mValues.clear();
  }

  public ContentValues getAll()
  {
    return mValues;
  }

  public void setValue(int columnId, String value)
  {
    mValues.put(mTable.getColumnName(columnId), value.trim());
  }

  public void setValue(int columnId, int value)
  {
    mValues.put(mTable.getColumnName(columnId), value);
  }

  public void setValue(int columnId, long value)
  {
    mValues.put(mTable.getColumnName(columnId), value);
  }

  public void setValue(int columnId, double value)
  {
    mValues.put(mTable.getColumnName(columnId), value);
  }

  public void setValue(int columnId, boolean value)
  {
    mValues.put(mTable.getColumnName(columnId), value);
  }

  public void setValueCurrentTime(int columnId)
  {
    final Calendar datetime = Calendar.getInstance();
    mValues.put(mTable.getColumnName(columnId), datetime.getTimeInMillis());
  }

  /**
   * Checks if all required values are present in collection.
   *
   * @return true if there is no missing value, or false otherwise.
   */
  public boolean valuesComplete()
  {
    for (int i = 0; i < mTable.mVecTableDefinition.length; i++) {
      final DataColumn field = mTable.mVecTableDefinition[i];
      if (field.bForEdit && (!field.bCanBeNull)) {
        if (!mValues.containsKey(field.name)) {
          return false;
        }
        // in case of blank value.
        final String sValue = mValues.get(field.name).toString().trim();
        if (sValue.length() == 0) {
          return false;
        }
      }
    }
    return true;
  }

  /* Gathers the values of a current row where the cursor points at. */
  private void getValuesFromCursor()
  {
    for (int i = 0; i < mTable.mVecTableDefinition.length; i++) {
      final DataColumn column = mTable.mVecTableDefinition[i];
      if (column.bPrimaryKey) {
        continue;
      }

      final int columnId = column.getIdentifier();
      switch (column.type) {
        case DataColumn.TYPE_INT :
          mValues.put(column.name, mInputCursor.getLong(columnId));
          break;
        case DataColumn.TYPE_BOOL :
          mValues.put(column.name, (mInputCursor.getInt(columnId) == 1));
          break;
        case DataColumn.TYPE_NUMERIC :
          mValues.put(column.name, mInputCursor.getDouble(columnId));
          break;
        case DataColumn.TYPE_TEXT :
          mValues.put(column.name, mInputCursor.getString(columnId));
          break;
      }
    }
  }

  public String getString(int columnId)
  {
    return mValues.getAsString(mTable.getColumnName(columnId));
  }

  public int getInteger(int columnId)
  {
    return mValues.getAsInteger(mTable.getColumnName(columnId));
  }

  public long getLong(int columnId)
  {
    return mValues.getAsLong(mTable.getColumnName(columnId));
  }

  public boolean getBool(int columnId)
  {
    return mValues.getAsBoolean(mTable.getColumnName(columnId));
  }

  public double getDouble(int columnId)
  {
    return mValues.getAsDouble(mTable.getColumnName(columnId));
  }

  public long getDateTime(int columnId)
  {
    return getLong(columnId) + timeZone.getRawOffset();
  }

  public Date getDateTimeAsDate(int columnId)
  {
    final long lTimeMs = getLong(columnId) + timeZone.getRawOffset();
    return new Date(lTimeMs);
  }

  public String getDateTimeAsString(int columnId)
  {
    final long lTimeMs = getLong(columnId) + timeZone.getRawOffset();
    return mDateFormat.format(new Date(lTimeMs));
  }
}
